CpSelected =[]
AmmoSelected = []
knownCps =[]
knownAmmos = []
AmmoTaken = [0,0,0,0,0,0]
AmmoTakenById = [-1,-1,-1,-1,-1,-1]
WaitingAmmoAgents = []
standOnCp = 0
runOnce = 0
initialLoc =()
enemyInitialLoc =()
shallEnemy = []
shallFriend = []
standOnCpId = -1
DifferentRegion = []
EscapeLoc = ()
StateOfWar = 0
CallForHelp = ()
CallForHelpAgentLoc = []
CallForHelpAgentId = []
sharedEnemyLoc = ()



class Agent(object):

    NAME = "Usurped_the_Throne" # Replay filenames and console output will contain this name.
    
    #defined on Monday
    flagCp = 0;

    def __init__(self, id, team, settings=None, field_rects=None, field_grid=None, nav_mesh=None):
       
        self.id = id
        self.team = team
        self.mesh = nav_mesh
        self.grid = field_grid
        self.settings = settings
        self.goal = None
        
        pass



    def observe(self, observation):
        self.observation = observation
        self.selected = observation.selected       

    def action(self):
            global knownAmmos   
            global standOnCp
            global standOnCpId
            global StateOfWar
        #if self.id==0 or self.id==1 or self.id==2:
            obs = self.observation
            self.computeInfo()
                  
                
            #obtain goal, shoot
            if StateOfWar ==0:
                self.goal = self.computeGoalWin()
            elif StateOfWar ==1:
                print "I am Loosing, change the Strategy!!!"
                self.goal = self.computeGoalLose()
            strategy = 0
            if len(self.goal)>2:
                strategy = self.goal[2]
                self.goal = self.goal[0:2]
                                
            shoot = self.computeShoot()

            # Compute path, angle and drive
            path = find_path(obs.loc, self.goal, self.mesh, self.grid, self.settings.tilesize)
            if path:
                dx = path[0][0]-obs.loc[0]
                dy = path[0][1]-obs.loc[1]
                turn = angle_fix(math.atan2(dy, dx)-obs.angle)
                if turn > self.settings.max_turn or turn < -self.settings.max_turn:
                    shoot = False
                speed = (dx**2 + dy**2)**0.5
            else:
                turn = 0
                speed = 0
            
            
            if strategy == 1 :
                speed = (dx**2 + dy**2)**0.45
                #print "slow down now@@@@@"
                
            
            if strategy == -1:# have no goal, turn
                speed = 0
                turn = 2
                #print "Have no goal, turn by self"
                
            if strategy ==4 :#kill till end
                speed = (dx**2 + dy**2)**0.65

            if enemyInitialLoc:
                if (self.team==0 and strategy ==6 and obs.loc[0]>=enemyInitialLoc[0]-100 and enemyInitialLoc[1]-60<=obs.loc[1]<=enemyInitialLoc[1]+60) or (self.team==1 and strategy ==6 and obs.loc[0]<=enemyInitialLoc[0]+100 and enemyInitialLoc[1]-60<=obs.loc[1]<=enemyInitialLoc[1]+60) :
                    speed = 0
                    print "I will usurped the throne!"
                    if shoot ==True and (self.team == 0 and self.goal[0] >= enemyInitialLoc[0] and enemyInitialLoc[1]<= self.goal[1] <= enemyInitialLoc[1]+15) or shoot ==True and (self.team == 1 and self.goal[0] <= enemyInitialLoc[0] and enemyInitialLoc[1]<= self.goal[1] <= enemyInitialLoc[1]+15):
                        shoot = False
                        #print "I cannot shoot enemy in his base, but wait!!!"
            
            if abs(turn)> 1.2:
                speed = 0
                #print "stop and turn"
            
            if shoot==True:
                speed = 0
            #print "****"+str(self.id)+"--my goal is :"+str(self.goal)+" turn:"+str(turn)+" shoot:"+str(shoot)+" speed: "+str(speed)
            #print "####"+str(obs.friends)
            return (turn,speed,shoot)
        #return (0, 0, False)

    def debug(self, surface):
        import pygame
        # First agent clears the screen
        if self.id == 0:
            surface.fill((0,0,0,0))
        # Selected agents draw their info
        if self.selected:
            if self.goal is not None:
                pygame.draw.line(surface,(0,0,0),self.observation.loc, self.goal)

    def finalize(self, interrupted=False):
        pass

    
    

    '''here compute the information for the war: AmmoList , enemy base location  
    '''   
    def computeInfo(self):
        global runOnce
        global enemyInitialLoc
        global knownAmmos
        global WaitingAmmoAgents
        global AmmoTakenById
        global AmmoTaken
        global DifferentRegion
        global EscapeLoc
        global StateOfWar
        #calculate all information related to WAR 
        obs = self.observation
        
        if runOnce ==0:
            #calculate 3 regions
            DifferentRegion = [obs.cps[0][0] , obs.cps[1][0], obs.cps[2][0]]
            DifferentRegion.sort()
            Cps = [obs.cps[0][0:2] , obs.cps[1][0:2], obs.cps[2][0:2]]
            #calculate escape Loc
            for element in Cps:
                if element[0]==328:
                    EscapeLoc = element            
            runOnce = 1
        
        '''
        if self.team == 0 :
            if (obs.score[1]-obs.score[0])>200:
            #if obs.score[0]<520:
                StateOfWar = 1
            else:
                StateOfWar = 0
        
        if self.team == 1:
            if(obs.score[0]-obs.score[1])>200:
            #if obs.score[1]<510:
                StateOfWar = 1
            else:
                StateOfWar = 0
        '''
        
        if self.id==2 and runOnce==1:
            #calculate enemy base Loc
            initialLoc = obs.loc
            enemyInitialLoc = (328+328-initialLoc[0],initialLoc[1])
            #print "red---initial Loc : "+str(self.id)+" "+str(initialLoc)
            print enemyInitialLoc
            runOnce=2       
        
        
            #print "the map is divided into 3 regions : "+str(DifferentRegion)
            #print "escape Loc : "+str(EscapeLoc)
        
            
        if len(knownAmmos)<6:
            for element in knownAmmos:
                ammoX = 328+328-element[0][0]
                ammoY = element[0][1]
                newAmmo = [(ammoX,ammoY)]
                doAppendAmmo = 0
                for element in knownAmmos:
                    if newAmmo == element:
                        doAppendAmmo = 1
                if doAppendAmmo ==0:
                    knownAmmos.append(newAmmo)
        else:
            if len(WaitingAmmoAgents)>0:
                for agentId in WaitingAmmoAgents:
                    if self.id == agentId and obs.ammo>0:
                        WaitingAmmoAgents.remove(agentId)
                        agentIndex = AmmoTakenById.index(agentId)
                        AmmoTakenById[agentIndex]=-1
                        AmmoTaken[agentIndex] = 0
        

        if self.id == 0:
            #print obs.score
            #print "knownAmmos "+str(knownAmmos)
            '''
            print "WaitingAmmoAgents  "+str(WaitingAmmoAgents)
            print "AmmoTaken  "+str(AmmoTaken)
            print "AmmoTakenById  "+str(AmmoTakenById)
            '''
    
    
    ''' here is 3 methods : compute CP dist 
                            compute Ammo dist 
                            compute Enemy dist
    '''
    
    def computeCpDist(self):
        global knownCps
        global CpSelected
        obs = self.observation
        unknownCps = [obs.cps[0][0:3] , obs.cps[1][0:3], obs.cps[2][0:3]]
        knownCps =[]
        for cp in unknownCps:
            if self.team ==0:
                if cp[2]!=0:
                    knownCps.append(cp)
            if self.team ==1:
                if cp[2]!=1:
                    knownCps.append(cp)
        if knownCps !=[]:
            #print "unknown CP "+str(unknownCps)
            #print "known CP "+str(knownCps)
            #print "selected CP "+str(CpSelected)
            agentLoc = obs.loc
            cpsDist = [( abs(agentLoc[0] - cp[0])  + abs(agentLoc[1] - cp[1]) ) for cp in knownCps]
            minIndex = cpsDist.index(min(cpsDist))
            #add for cooperation 
            
            if len(knownCps)>1: 
                if knownCps[minIndex][0:2] == CpSelected:
                    knownCps.pop(minIndex)
                    targetCP = [knownCps[0][0:2]]
                    CpSelected = knownCps[0][0:2]
                else:
                    targetCP = [knownCps[minIndex][0:2]]
                    CpSelected = knownCps[minIndex][0:2]
            else:
                targetCP = [knownCps[minIndex][0:2]]
                CpSelected = knownCps[minIndex][0:2]
            
            #print "target CP---"+str(targetCP)
            #targetCP = [knownCps[minIndex][0:2]]
            return targetCP 
        else:
            return []

    
    def computAmmoDist(self):
        global AmmoSelected
        global knownAmmos
        obs = self.observation
        agentLoc = obs.loc
        ammopacks = filter(lambda x: x[2] == "Ammo", obs.objects)
        if ammopacks:
             ammoDist = [( abs(agentLoc[0] - ammo[0])  + abs(agentLoc[1] - ammo[1]) ) for ammo in ammopacks]
             minIndex = ammoDist.index(min(ammoDist))
             #add for cooperation
             #print str(self.id)+" ammopacks "+str(ammopacks)
             #print str(self.id)+" selected ammo"+str(AmmoSelected)
             if len(ammopacks)>1:
                 if ammopacks[minIndex][0:2] == AmmoSelected:
                     ammopacks.pop(minIndex)
                     targetAmmo = [ammopacks[0][0:2]]
                     AmmoSelected = ammopacks[0][0:2]
                 else:
                     targetAmmo = [ammopacks[minIndex][0:2]]
                     AmmoSelected = ammopacks[minIndex][0:2]
             else:
#                 if ammopacks[minIndex][0:2] == AmmoSelected:
#                     return []
#                 else:
                     targetAmmo = [ammopacks[minIndex][0:2]]
                     AmmoSelected = ammopacks[minIndex][0:2]
             #print str(self.id)+" target ammo "+str(targetAmmo)
             
             if len(knownAmmos)<6:
                if len(knownAmmos)==0:
                    knownAmmos.append(targetAmmo)
                #print "smaller than 6"
                doAppendAmmo = 0
                for element in knownAmmos:
                    if targetAmmo == element:
                        doAppendAmmo = 1
                if doAppendAmmo ==0:
                    knownAmmos.append(targetAmmo)
                    #print str(self.id)+" add one ammo to Known list"+str(targetAmmo)
             return targetAmmo
        else:
             return []

    def computEnemyDist(self):
        global enemyInitialLoc
        obs = self.observation
        agentLoc = obs.loc
        enemyPacks = obs.foes
        knownEnemyPacks =[]
        if enemyPacks!=[]:
            if self.team==0:
                for enemy in enemyPacks:
                    if enemy[0]< enemyInitialLoc[0] and (enemy[1]< enemyInitialLoc[1] or enemy[1]>=enemyInitialLoc[1]+15):
                        knownEnemyPacks.append(enemy)
            else:
                for enemy in enemyPacks:
                    if enemy[0]> enemyInitialLoc[0] and (enemy[1]< enemyInitialLoc[1] or enemy[1]>=enemyInitialLoc[1]+20):
                        knownEnemyPacks.append(enemy)
            
        if knownEnemyPacks!=[]:
            enemyDist =  [( abs(agentLoc[0] - enemy[0])  + abs(agentLoc[1] - enemy[1]) ) for enemy in knownEnemyPacks]
            minIndex = enemyDist.index(min(enemyDist))
            '''
            enemyAngle = []
            for enemy in enemypacks:
                #path = find_path(obs.loc, self.goal, self.mesh, self.grid, self.settings.tilesize)
                #if path:
                #dx = path[0][0]-obs.loc[0]
                #dy = path[0][1]-obs.loc[1]
                turn = angle_fix(math.atan2(enemy[1]-obs.loc[1], enemy[0]-obs.loc[0])-obs.angle)
                enemyAngle.append(turn)
            minIndex = enemyAngle.index(min(enemyAngle))
            '''
            #enemyAngle = [abs(enemy[2]) for enemy in enemypacks]
            #minIndex = enemyAngle.index(min(enemyAngle))
            targetEnemy = [knownEnemyPacks[minIndex][0:3]]
            return targetEnemy
        else:
            return []
    
    
    
    '''here are 2 methods : compute the Goal 
                            compute the shoot
    '''           
    def computeGoalWin(self):
        global AmmoTaken
        global AmmoTakenById 
        global WaitingAmmoAgents
        global standOnCp
        global standOnCpId
        global shallEnemy
        global shallFriend
        global DifferentRegion
        global CallForHelp
        global CallForHelpAgentLoc
        global CallForHelpAgentId
        global sharedEnemyLoc
        obs = self.observation
        agentLoc = obs.loc;
        # agent obtains 3 goals:Cp, Ammo, Enemy
        obtainCPList = self.computeCpDist()
        obtainAmmoList = self.computAmmoDist()
        obtainEnemyList = self.computEnemyDist()
        
        
        # 1.agent has no Ammo
        if obs.ammo==0:
                # 1.1 agent only sees Cp
                if obtainCPList !=[] and obtainAmmoList ==[] and obtainEnemyList ==[]:
                    self.goal = obtainCPList[0] 
                # 1.2 agent only sees Ammo
                if obtainAmmoList !=[] and obtainCPList ==[] and obtainEnemyList ==[]:
                    goToAmmo = 0
                    #print "friends Loc :"+str(obs.friends)
                    #print "Ammo Loc :"+str(obtainAmmoList[0])
                    for friend in obs.friends:
                        if obtainAmmoList[0][0]-15 < friend[0] < obtainAmmoList[0][0]+15 and obtainAmmoList[0][1]-15 < friend[1] < obtainAmmoList[0][1]+15:
                            goToAmmo = 1
                            #print "should not grab with friends"
                    if goToAmmo == 0:
                        #print "don't see friend???"
                        self.goal = obtainAmmoList[0]
                # 1.3 agent only sees Enemy----seldom run here
                if obtainEnemyList !=[] and obtainAmmoList ==[] and obtainCPList==[]:
                    self.goal = EscapeLoc + (4,)# RUSH!!!
                    #print "Escape!!??"
                # 1.4 agent sees Cp and Ammo together
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList ==[]:
                    distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) +0.00001 
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1]) +0.00001 
                    if  distAmmo < distCp:
                        goToAmmo = 0
                        for friend in obs.friends:
                            if obtainAmmoList[0][0]-15 < friend[0] < obtainAmmoList[0][0]+15 and obtainAmmoList[0][1]-15 < friend[1] < obtainAmmoList[0][1]+15:
                                goToAmmo = 1
                                #print "should not grab with friends"
                        if goToAmmo == 0:
                            self.goal = obtainAmmoList[0]
                        else:
                            self.goal = obtainCPList[0]
                    else:
                        self.goal = obtainCPList[0]
                # 1.5 agent sees Cp and Enemy together
                if obtainCPList !=[] and obtainEnemyList !=[] and obtainAmmoList ==[] :
                    distCp = abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) +0.00001 
                    distEnemy2Cp = abs(obtainEnemyList[0][0] - obtainCPList[0][0])+abs(obtainEnemyList[0][1] - obtainCPList[0][1])+0.00001 
                    #if distCp < distEnemy2Cp :
                    
                    self.goal = obtainCPList[0] + (4,)# RUSH!!!
                    #else:
                        #self.goal = EscapeLoc + (4,)# RUSH!!!
                # 1.6 agent sees Enemy and Ammo together
                if obtainEnemyList !=[] and obtainAmmoList !=[] and obtainCPList ==[] :
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                    distEnemy2Ammo = abs(obtainEnemyList[0][0] - obtainAmmoList[0][0])+abs(obtainEnemyList[0][1] - obtainAmmoList[0][1])+0.00001 
                    #if (distAmmo/distEnemy2Ammo) < 2.0 :
                    self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                    #else:
                       # self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                # 1.7 agent sees Cp and Enemy and Ammo altogether
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList !=[]:
                    distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1])+0.00001 
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                    distEnemy2Cp = abs(obtainEnemyList[0][0] - obtainCPList[0][0])+abs(obtainEnemyList[0][1] - obtainCPList[0][1])+0.00001 
                    distEnemy2Ammo = abs(obtainEnemyList[0][0] - obtainAmmoList[0][0])+abs(obtainEnemyList[0][1] - obtainAmmoList[0][1])+0.00001 
                    if distCp < distEnemy2Cp and distAmmo > distEnemy2Ammo:
                        self.goal = obtainCPList[0] + (4,)# RUSH!!!
                    if distCp > distEnemy2Cp and distAmmo < distEnemy2Ammo:
                        self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                    if distCp < distEnemy2Cp and distAmmo < distEnemy2Ammo:
                        self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                    if distCp > distEnemy2Cp and distAmmo > distEnemy2Ammo:
                        self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                # 1.8 agent sees nothing
                if obtainCPList ==[] and obtainAmmoList ==[] and obtainEnemyList ==[] :
                    #print str(self.id)+" I see nothing!???"
                    self.goal = None

            
                    
                # obtain all Ammos' info, start computing
                if len(knownAmmos)==6 and obtainAmmoList==[] :#and obtainEnemyList != []: #maybe need add Enemy
                        #compute cloest ammo and pick up
                        distAmmoList = []
                        for element in knownAmmos:
                            distAmmo = abs(obs.loc[0]-element[0][0])+abs(obs.loc[1]-element[0][1])
                            distAmmoList.append(distAmmo)
                        minIndex = distAmmoList.index(min(distAmmoList))
                        #check whether this ammo has been taken by friends
                        if AmmoTaken[minIndex]==0 or ( AmmoTaken[minIndex]==1 and self.id == AmmoTakenById[minIndex]):
                            AmmoTaken[minIndex]=1
                            AmmoTakenById[minIndex]=self.id
                            doAppendWaitingAgent = 0
                            if len(WaitingAmmoAgents)>0:
                                for waitingAgent in WaitingAmmoAgents:
                                    if self.id == waitingAgent:
                                         doAppendWaitingAgent =1
                            if doAppendWaitingAgent == 0 :
                                WaitingAmmoAgents.append(self.id)
                            targetAmmo = knownAmmos[minIndex][0:2]
                            if obtainCPList ==[]:
                                self.goal = targetAmmo[0]
                            else:
                                distTargetAmmo = abs(agentLoc[0]-targetAmmo[0][0])+abs(agentLoc[1]-targetAmmo[0][1])+0.00001
                                distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1])+0.00001
                                if distTargetAmmo<distCp:
                                   self.goal = targetAmmo[0]
                                else:
                                   self.goal = obtainCPList[0]+(4,)#rush!!!     

          
        # 2.agent has Ammo
        elif obs.ammo>0:    

                # 2.1 agent only sees Cp 
                if obtainCPList !=[] and obtainAmmoList ==[] and obtainEnemyList ==[]:
                    self.goal = obtainCPList[0] 
                # 2.2 agent only sees Ammo
                if obtainAmmoList !=[] and obtainCPList ==[] and obtainEnemyList ==[]:
                    if (self.team ==0 and obtainAmmoList[0][0]>328 and obs.ammo>3) or (self.team ==1 and obtainAmmoList[0][0]<328 and obs.ammo>3): 
                        self.goal = obtainAmmoList[0]
                # 2.3 agent only sees Enemy
                if obtainEnemyList !=[] and obtainAmmoList ==[] and obtainCPList==[]:
                    self.goal = obtainEnemyList[0][0:2]+(1,) #slow to kill
                # 2.4 agent sees Cp and Ammo together
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList ==[]:
                    distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) +0.00001
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1]) +0.00001 
                    angleCp=angle_fix(math.atan2(obtainCPList[0][1]-agentLoc[1], obtainCPList[0][0]-agentLoc[0])-obs.angle)
                    angleAmmo=angle_fix(math.atan2(obtainAmmoList[0][1]-agentLoc[1], obtainAmmoList[0][0]-agentLoc[0])-obs.angle)
                    if  distAmmo < distCp and angleCp < angleAmmo:
                        goToAmmo = 0
                        for friend in obs.friends:
                            if obtainAmmoList[0][0]-15 < friend[0] < obtainAmmoList[0][0]+15 and obtainAmmoList[0][1]-15 < friend[1] < obtainAmmoList[0][1]+15:
                                goToAmmo = 1
                                print "should not grab with friends"
                        if goToAmmo == 0:
                            self.goal = obtainAmmoList[0]
                        else:
                            self.goal = obtainCPList[0]
                    else:
                        self.goal = obtainCPList[0]                    
                # 2.5 agent sees Cp and Enemy together
                if obtainCPList !=[] and obtainEnemyList !=[] and obtainAmmoList ==[] :
                    if obs.ammo>2:
                    #'''
                        distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1])+0.00001 
                        distEnemy=abs(agentLoc[0] - obtainEnemyList[0][0])+abs(agentLoc[1] - obtainEnemyList[0][1])+0.00001 
                        angleCp=angle_fix(math.atan2(obtainCPList[0][1]-agentLoc[1], obtainCPList[0][0]-agentLoc[0])-obs.angle)
                        angleEnemy=angle_fix(math.atan2(obtainEnemyList[0][1]-agentLoc[1], obtainEnemyList[0][0]-agentLoc[0])-obs.angle)
                        if (distCp/distEnemy) < 3.0 and angleCp < angleEnemy:
                            self.goal = obtainCPList[0] + (4,)# RUSH!!!
                        else:
                            self.goal = obtainEnemyList[0][0:2]
                    #'''
                    else:
                        self.goal = obtainEnemyList[0][0:2]+(1,) #slow to kill
                # 2.6 agent sees Enemy and Ammo together
                if obtainEnemyList !=[] and obtainAmmoList !=[] and obtainCPList ==[] :
                    if obs.ammo>2:
                        #'''
                        distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                        distEnemy2Ammo = abs(obtainEnemyList[0][0] - obtainAmmoList[0][0])+abs(obtainEnemyList[0][1] - obtainAmmoList[0][1])+0.00001 
                        angleAmmo=angle_fix(math.atan2(obtainAmmoList[0][1]-agentLoc[1], obtainAmmoList[0][0]-agentLoc[0])-obs.angle)
                        angleEnemy=angle_fix(math.atan2(obtainEnemyList[0][1]-agentLoc[1], obtainEnemyList[0][0]-agentLoc[0])-obs.angle)
                        if (distAmmo/distEnemy2Ammo) < 3.0 and angleAmmo < angleEnemy:
                            self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                        else:
                            self.goal = obtainEnemyList[0][0:2]
                        # '''
                    else:
                        self.goal = obtainEnemyList[0][0:2]+(1,) #slow to kill
                # 2.7 agent sees Cp and Enemy and Ammo altogether
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList !=[]:
                    if obs.ammo<2:
                        #
                        #'''
                        distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1])+0.00001 
                        distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                        distEnemy=abs(agentLoc[0] - obtainEnemyList[0][0])+abs(agentLoc[1] - obtainEnemyList[0][1])+0.00001 
                        angleCp=angle_fix(math.atan2(obtainCPList[0][1]-agentLoc[1], obtainCPList[0][0]-agentLoc[0])-obs.angle)
                        angleAmmo=angle_fix(math.atan2(obtainAmmoList[0][1]-agentLoc[1], obtainAmmoList[0][0]-agentLoc[0])-obs.angle)
                        angleEnemy=angle_fix(math.atan2(obtainEnemyList[0][1]-agentLoc[1], obtainEnemyList[0][0]-agentLoc[0])-obs.angle)                    
                        if distCp<distEnemy and distCp<distAmmo and angleCp<angleEnemy and angleCp<angleAmmo:
                            self.goal = obtainCPList[0]
                        if distAmmo<distEnemy and distAmmo<distCp and angleAmmo<angleEnemy and angleAmmo<angleCp:
                            self.goal = obtainAmmoList[0]
                        else:
                            self.goal = obtainEnemyList[0][0:2]
                        #'''
                    else:
                        self.goal = obtainEnemyList[0][0:2]+(1,) #slow to kill
                # 2.8 agent sees nothing
                if obtainCPList ==[] and obtainAmmoList ==[] and obtainEnemyList ==[] :
                    self.goal = None
                    
                    
                '''
                unknownCps = [obs.cps[0][0:2] , obs.cps[1][0:2], obs.cps[2][0:2]]
                friendsLoc = obs.friends
                for cp in unknownCps:
                    #for friendLoc in friendsLoc:
                        #if friendLoc != cp :
                            if (self.team == 0 and cp[0]-20<agentLoc[0]<cp[0]+20 and cp[1]-20<agentLoc[1]<cp[1]+20 and cp[0] >=328) or (self.team == 1 and cp[0]-20<agentLoc[0]<cp[0]+20 and cp[1]-20<agentLoc[1]<cp[1]+20 and cp[0] <=328):
                                #standOnCp = 1
                                #standOnCpId = self.id
                                    if len(self.goal) == 2:
                                        self.goal =self.goal+(2,)
                '''
        # 3. no matter where is agent, here is for corporation  
        '''  
        # 3.1 attack Enemy base together
        if obtainCPList==[] and obs.ammo>3 : 
            #print "Attack together@@@@@@"
            if  (self.team == 0 and agentLoc[0] < 400) or (self.team == 1 and agentLoc[0] > 150) and obtainEnemyList==[]: # only for red team
                self.goal = enemyInitialLoc
                #print str(self.goal)+"Attack together and walk fast"
            else:
                self.goal = enemyInitialLoc+(1,) 
        '''        
        '''
        # 3.2 help friend to attack emeny
        if obtainCPList==[] and CallForHelp ==() and obtainEnemyList !=[] :
            CallForHelp = agentLoc
            print "agent-"+str(self.id)+" add a enemy and call for help to Loc : "+str(CallForHelp)
        if obtainCPList==[] and obtainEnemyList ==[] and CallForHelp !=():# and obs.ammo>0: # modify        
            print "I am going to help, my id = "+str(self.id)
            self.goal = CallForHelp
            for member in CallForHelpAgentId:
                if self.id != member:
                    CallForHelpAgentId.append(self.id)

        #print obs.hit
        if  CallForHelp !=() : # only for red team
            print "the list who going to help : "+str(CallForHelpAgentId)
            for member in CallForHelpAgentId:
                if self.id == member and obs.hit == 1: 
                    print "I hit the enemy!!!  update CallForHelp"
                    CallForHelp =()
                    CallForHelpAgentId =[]
        '''
        '''
       # 3.3 share self.goal with friends
        if obtainCPList ==[] and obtainEnemyList==[] and obs.ammo>0:
            if obs.friends !=[]:
                   friendDist = [abs(agentLoc[0]-member[0])+abs(agentLoc[1]-member[1]) for member in obs.friends]
                   minIndex = friendDist.index(min(friendDist))
                   print "I have a list of friends :"+str(obs.friends)
                   print "The friendDist :"+str(friendDist)
                   self.goal = obs.friends[minIndex]
                   print "I goal is one of my friend :"+str(self.goal)
        '''
        '''
        # 3.4 patrol and defend 3 CP
        if obtainCPList ==[] and obtainEnemyList==[] and obs.ammo>0:
            #only for red team
            defendCp = []
            for cp in obs.cps:
                if cp[0]>=328:
                    defendCp.append(cp[0:2])
            print "defend Cp : "+str(defendCp)
            self.goal = defendCp[random.randint(0,len(defendCp)-1)]
            print "i want to defend : "+str(self.goal)
        
        '''
        
        #3.5 rotate and report enemy to teammate
        toShareEnemy = 0
        if self.team == 0:
            credit = obs.cps[0][2]+obs.cps[1][2]+obs.cps[2][2]
            if credit <= 1:
                toShareEnemy = 1
        else:#
            if obs.cps[0][2]==1 and obs.cps[1][2]==1:
                toShareEnemy = 1   
            elif obs.cps[0][2]==1 and obs.cps[2][2]==1:
                toShareEnemy = 1   
            elif obs.cps[1][2]==1 and obs.cps[2][2]==1:
                toShareEnemy = 1   
            elif obs.cps[0][2]==1 and obs.cps[1][2]==1 and obs.cps[2][2]==1:
                toShareEnemy = 1   
            
        if toShareEnemy == 1 and obtainEnemyList==[] and obs.ammo>0 :
            if sharedEnemyLoc ==() and obtainCPList ==[]:
                self.goal = obs.cps[random.randint(0,len(obs.cps)-1)][0:2]+(-1,)
            else:
                self.goal = sharedEnemyLoc
                #print "I go to shared enemy "+ str(sharedEnemyLoc)
        
        if toShareEnemy == 1 and obtainEnemyList != []:
            sharedEnemyLoc = obtainEnemyList[0][0:2]+(1,) #slow to kill
            #print "I share a enemy " + str(sharedEnemyLoc)
            #if obs.ammo > 0:
                #self.goal = sharedEnemyLoc
            
        
        if self.team == 0 and sharedEnemyLoc !=():     
            if sharedEnemyLoc[0]-40<agentLoc[0]<sharedEnemyLoc[0]+40 and obs.hit ==1: # only for red team
                sharedEnemyLoc = ()
                #print "clear the share enemy"
                
        if self.team == 1 and sharedEnemyLoc !=():     
            if sharedEnemyLoc[0]-40<agentLoc[0]<sharedEnemyLoc[0]+40 and obs.hit ==0: # only for blue team
                sharedEnemyLoc = ()
                #print "clear the share enemy"
        
        #no shared enemy, go to enemy base
        if obtainCPList ==[] and obtainEnemyList ==[] and obs.ammo>2:
            if obtainEnemyList == []:
                    self.goal = enemyInitialLoc+(6,)
            

        # Walk to random CP
        if self.goal is None and len(knownAmmos)<6:
            self.goal = obs.cps[random.randint(0,len(obs.cps)-1)][0:2]+(-1,)

        if self.goal is None and len(knownAmmos)>4:
            #print "run here"
            self.goal = knownAmmos[random.randint(0,len(knownAmmos)-1)][0]
            #self.goal = knownAmmos[random.randint(0,len(knownAmmos)-1)][0]+(-1,)
            #print self.goal


        
        if self.goal ==():
            #print "I have no goal"
            self.goal = obs.cps[random.randint(0,len(obs.cps)-1)][0:2]+(-1,)
        

        '''
        if enemyInitialLoc and self.goal != None:
            #print self.goal 
            #print enemyInitialLoc
            if (self.team == 0 and self.goal[0] >= enemyInitialLoc[0] and enemyInitialLoc[1]<= self.goal[1] <= enemyInitialLoc[1]+15 and obs.loc[0] >= enemyInitialLoc[0] - 80):# or (self.team == 1 and self.goal[0] <= enemyInitialLoc[0] and enemyInitialLoc[1]<= self.goal[1] <= (enemyInitialLoc[1]+15) and obs.loc[0] <= (enemyInitialLoc[0] + 70)) :
                    for cp in obs.cps:
                        if cp[0] > 328:
                                self.goal = cp[0:2] 
                                print "go back~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
       ''' 
        
        
        #3.6 don't make enemy in base as goal
#        if  enemyInitialLoc[0] <= self.goal[0] and enemyInitialLoc[1]<= self.goal[1] <= enemyInitialLoc[1]+50:
#            
#            print "cancel the goal in base"
#            self.goal = self.goal = knownAmmos[random.randint(0,len(knownAmmos)-1)][0]
                   
        '''
        # 3.3 walk together if CP belongs to us
        if obtainCPList==[] and obs.ammo>0:
            print 
        '''
        
                #print str(self.goal)+"Attack together and walk slow"
        '''
        # 3.1 help friends   
        if obs.ammo>0 and len(shallEnemy)>0:
                if shallFriend>0:
                    for member in shallFriend:
                        if agentLoc == member:
                            self.goal = shallEnemy
                            print "I have to help my friend"
        # shall enemy with friends
        if obtainEnemyList!=[] :
            shallEnemy = obtainEnemyList[0][0:2]
            shallFriend = obs.friends
        '''        

        return self.goal 
    
    
    def computeGoalLose(self):
            global initialLoc
            global runOnce
            global enemyInitialLoc
        #if self.id==1 :#or self.id==0:
            obs = self.observation
            
            
            
            #new add--- obtain the 3 CP sorted positions
            obtainCPList = self.computeCpDist()
            obtainAmmoList = self.computAmmoDist()
            obtainEnemyList = self.computEnemyDist()
            
            agentLoc = obs.loc;
            
                      
            # I see CP and Ammo at same time
            if obtainCPList !=[]:
                if obtainAmmoList !=[]:
                    distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) 
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])
                    #print str(distCp) +" vs "+str(distAmmo)
                    if distAmmo/distCp < 0.5 and obs.ammo<3:
                        self.goal = obtainAmmoList[0]
                        #print "choose ammo"
                    else:
                        self.goal = obtainCPList[0]
                        #print "choose cp"
                else:
                    self.goal = obtainCPList[0]
            
            if obtainCPList ==[] and obtainAmmoList !=[]:
                self.goal = obtainAmmoList[0]
                
            
            
            if self.goal is not None and point_dist(self.goal, obs.loc) < self.settings.tilesize:
                self.goal = None
                
            
            # Walk to random CP
            if self.goal is None:
                    self.goal = obs.cps[random.randint(0,len(obs.cps)-1)][0:2]
            
            return self.goal
    
    
  
    def computeGoal2(self):
        global AmmoTaken
        global AmmoTakenById 
        global WaitingAmmoAgents
        global standOnCp
        global standOnCpId
        global shallEnemy
        global shallFriend
        global DifferentRegion
        obs = self.observation
        agentLoc = obs.loc;
        # agent obtains 3 goals:Cp, Ammo, Enemy
        obtainCPList = self.computeCpDist()
        obtainAmmoList = self.computAmmoDist()
        obtainEnemyList = self.computEnemyDist()
        
        
        # 1.agent has no Ammo
        if obs.ammo==0:
            # 1.1 agent is in Region-1 (DifferentRegion[0])
            if agentLoc[0] < DifferentRegion[0]:
                # 1.1.1 agent only sees Cp
                if obtainCPList !=[] and obtainAmmoList ==[] and obtainEnemyList ==[]:
                    self.goal = obtainCPList[0] 
                # 1.1.2 agent only sees Ammo
                if obtainAmmoList !=[] and obtainCPList ==[] and obtainEnemyList ==[]:
                    goToAmmo = 0
                    print "friends Loc :"+str(obs.friends)
                    print "Ammo Loc :"+str(obtainAmmoList[0])
                    for friend in obs.friends:
                        if obtainAmmoList[0][0]-15 < friend[0] < obtainAmmoList[0][0]+15 and obtainAmmoList[0][1]-15 < friend[1] < obtainAmmoList[0][1]+15:
                            goToAmmo = 1
                            print "should not grab with friends"
                    if goToAmmo == 0:
                        print "don't see friend???"
                        self.goal = obtainAmmoList[0]
                # 1.1.3 agent only sees Enemy----seldom run here
                if obtainEnemyList !=[] and obtainAmmoList ==[] and obtainCPList==[]:
                    self.goal = EscapeLoc + (4,)# RUSH!!!
                # 1.1.4 agent sees Cp and Ammo together
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList ==[]:
                    #print "We are see both but stuck in ammo"
                    distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) +0.00001 
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1]) +0.00001 
                    print "friends Loc :"+str(obs.friends)
                    print "Ammo Loc :"+str(obtainAmmoList[0])
                    if  distAmmo < distCp:
                        goToAmmo = 0
                        for friend in obs.friends:
                            if obtainAmmoList[0][0]-15 < friend[0] < obtainAmmoList[0][0]+15 and obtainAmmoList[0][1]-15 < friend[1] < obtainAmmoList[0][1]+15:
                                goToAmmo = 1
                                print "should not grab with friends"
                        if goToAmmo == 0:
                            print "don't see friend???"
                            self.goal = obtainAmmoList[0]
                        else:
                            self.goal = obtainCPList[0]
                    else:
                        self.goal = obtainCPList[0]
                # 1.1.5 agent sees Cp and Enemy together
                if obtainCPList !=[] and obtainEnemyList !=[] and obtainAmmoList ==[] :
                    distCp = abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) +0.00001 
                    distEnemy2Cp = abs(obtainEnemyList[0][0] - obtainCPList[0][0])+abs(obtainEnemyList[0][1] - obtainCPList[0][1])+0.00001 
                    if distCp < distEnemy2Cp :
                        self.goal = obtainCPList[0] + (4,)# RUSH!!!
                    else:
                        self.goal = EscapeLoc + (4,)# RUSH!!!
                # 1.1.6 agent sees Enemy and Ammo together
                if obtainEnemyList !=[] and obtainAmmoList !=[] and obtainCPList ==[] :
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                    distEnemy2Ammo = abs(obtainEnemyList[0][0] - obtainAmmoList[0][0])+abs(obtainEnemyList[0][1] - obtainAmmoList[0][1])+0.00001 
                    if (distAmmo/distEnemy2Ammo) < 2.0 :
                        self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                    else:
                        self.goal = EscapeLoc + (4,)# RUSH!!!
                # 1.1.7 agent sees Cp and Enemy and Ammo altogether
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList !=[]:
                    distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1])+0.00001 
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                    distEnemy2Cp = abs(obtainEnemyList[0][0] - obtainCPList[0][0])+abs(obtainEnemyList[0][1] - obtainCPList[0][1])+0.00001 
                    distEnemy2Ammo = abs(obtainEnemyList[0][0] - obtainAmmoList[0][0])+abs(obtainEnemyList[0][1] - obtainAmmoList[0][1])+0.00001 
                    if distCp < distEnemy2Cp and distAmmo > distEnemy2Ammo:
                        self.goal = obtainCPList[0] + (4,)# RUSH!!!
                    if distCp > distEnemy2Cp and distAmmo < distEnemy2Ammo:
                        self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                    if distCp < distEnemy2Cp and distAmmo < distEnemy2Ammo:
                        self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                    if distCp > distEnemy2Cp and distAmmo > distEnemy2Ammo:
                        self.goal = EscapeLoc + (4,)# RUSH!!!
                # 1.1.8 agent sees nothing
                if obtainCPList ==[] and obtainAmmoList ==[] and obtainEnemyList ==[] :
                    print str(self.id)+" I see nothing!???"
                    self.goal = None

            # 1.2 agent is in Region-2 (DifferentRegion[0]->DifferentRegion[2])
            elif DifferentRegion[1] <= agentLoc[0] < DifferentRegion[2]:
                # 1.2.1 agent only sees Cp and Cp is closest one
                if obtainCPList !=[] and obtainAmmoList ==[] and obtainEnemyList ==[]:
                    self.goal = obtainCPList[0] 
                # 1.2.2 agent only sees Ammo
                if obtainAmmoList !=[] and obtainCPList ==[] and obtainEnemyList ==[]:
                    print "friends Loc :"+str(obs.friends)
                    print "Ammo Loc :"+str(obtainAmmoList[0])
                    goToAmmo = 0
                    for friend in obs.friends:
                        if obtainAmmoList[0][0]-15 < friend[0] < obtainAmmoList[0][0]+20 and obtainAmmoList[0][1]-20 < friend[1] < obtainAmmoList[0][1]+20:
                            goToAmmo = 1
                            print "should not grab with friends"
                    if goToAmmo == 0:
                        print "don't see friend???"
                        self.goal = obtainAmmoList[0]                    
                # 1.2.3 agent only sees Enemy
                if obtainEnemyList !=[] and obtainAmmoList ==[] and obtainCPList==[]:
                    self.goal = EscapeLoc + (4,)# RUSH!!!
                # 1.2.4 agent sees Cp and Ammo together
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList ==[]:
                    distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) +0.00001 
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1]) +0.00001 
                    if  distAmmo < distCp:
                        print "friends Loc :"+str(obs.friends)
                        print "Ammo Loc :"+str(obtainAmmoList[0])                                               
                        goToAmmo = 0
                        for friend in obs.friends:
                            if obtainAmmoList[0][0]-20 < friend[0] < obtainAmmoList[0][0]+20 and obtainAmmoList[0][1]-20 < friend[1] < obtainAmmoList[0][1]+20:
                                goToAmmo = 1
                                print "should not grab with friends"
                        if goToAmmo == 0:
                            print "don't see friend???"
                            self.goal = obtainAmmoList[0]
                        else:
                            self.goal = obtainCPList[0]
                    else:
                        self.goal = obtainCPList[0]
                # 1.2.5 agent sees Cp and Enemy together
                if obtainCPList !=[] and obtainEnemyList !=[] and obtainAmmoList ==[] :
                    distCp = abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) +0.00001 
                    distEnemy2Cp = abs(obtainEnemyList[0][0] - obtainCPList[0][0])+abs(obtainEnemyList[0][1] - obtainCPList[0][1])+0.00001 
                    if distCp < distEnemy2Cp :
                        self.goal = obtainCPList[0] + (4,)# RUSH!!!
                    else:
                        self.goal = EscapeLoc + (4,)# RUSH!!!
                # 1.2.6 agent sees Enemy and Ammo together
                if obtainEnemyList !=[] and obtainAmmoList !=[] and obtainCPList ==[] :
                    self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                # 1.2.7 agent sees Cp and Enemy and Ammo altogether
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList !=[]:
                    distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1])+0.00001 
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                    distEnemy2Cp = abs(obtainEnemyList[0][0] - obtainCPList[0][0])+abs(obtainEnemyList[0][1] - obtainCPList[0][1])+0.00001 
                    distEnemy2Ammo = abs(obtainEnemyList[0][0] - obtainAmmoList[0][0])+abs(obtainEnemyList[0][1] - obtainAmmoList[0][1])+0.00001 
                    if distCp < distEnemy2Cp and distAmmo > distEnemy2Ammo:
                        self.goal = obtainCPList[0] + (4,)# RUSH!!!
                    if distCp > distEnemy2Cp and distAmmo < distEnemy2Ammo:
                        self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                    if distCp < distEnemy2Cp and distAmmo < distEnemy2Ammo:
                        self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                    if distCp > distEnemy2Cp and distAmmo > distEnemy2Ammo:
                        self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                # 1.2.8 agent sees nothing
                if len(knownAmmos)<6 and obtainCPList ==[] and obtainAmmoList ==[] and obtainEnemyList ==[] :
                    self.goal = None

            # 1.3 agent is in Region-3 (DifferentRegion[2])
            elif agentLoc[0] >= DifferentRegion[2]:
                # 1.3.1 agent only sees Cp and Cp is closest one
                if obtainCPList !=[] and obtainAmmoList ==[] and obtainEnemyList ==[]:
                    self.goal = obtainCPList[0] 
                # 1.3.2 agent only sees Ammo
                if obtainAmmoList !=[] and obtainCPList ==[] and obtainEnemyList ==[]:
                    goToAmmo = 0
                    for friend in obs.friends:
                        if obtainAmmoList[0][0]-20 < friend[0] < obtainAmmoList[0][0]+20 and obtainAmmoList[0][1]-20 < friend[1] < obtainAmmoList[0][1]+20:
                            goToAmmo = 1
                            print "should not grab with friends"
                    if goToAmmo == 0:
                        print "don't see friend???"
                        self.goal = obtainAmmoList[0]
                # 1.3.3 agent only sees Enemy----seldom run here
                if obtainEnemyList !=[] and obtainAmmoList ==[] and obtainCPList==[]:
                    self.goal = EscapeLoc + (4,)# RUSH!!!
                # 1.3.4 agent sees Cp and Ammo together
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList ==[]:
                    distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) +0.00001 
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1]) +0.00001 
                    if  distAmmo < distCp:
                        goToAmmo = 0
                        for friend in obs.friends:
                            if obtainAmmoList[0][0]-20 < friend[0] < obtainAmmoList[0][0]+20 and obtainAmmoList[0][1]-20 < friend[1] < obtainAmmoList[0][1]+20:
                                goToAmmo = 1
                                print "should not grab with friends"
                        if goToAmmo == 0:
                            print "don't see friend???"
                            self.goal = obtainAmmoList[0]
                        else:
                            self.goal = obtainCPList[0]
                    else:
                        self.goal = obtainCPList[0]
                # 1.3.5 agent sees Cp and Enemy together
                if obtainCPList !=[] and obtainEnemyList !=[] and obtainAmmoList ==[] :
                    distCp = abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) +0.00001 
                    distEnemy2Cp = abs(obtainEnemyList[0][0] - obtainCPList[0][0])+abs(obtainEnemyList[0][1] - obtainCPList[0][1])+0.00001 
                    if distCp < distEnemy2Cp :
                        self.goal = obtainCPList[0] + (4,)# RUSH!!!
                    else:
                        self.goal = EscapeLoc + (4,)# RUSH!!!
                # 1.3.6 agent sees Enemy and Ammo together
                if obtainEnemyList !=[] and obtainAmmoList !=[] and obtainCPList ==[] :
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                    distEnemy2Ammo = abs(obtainEnemyList[0][0] - obtainAmmoList[0][0])+abs(obtainEnemyList[0][1] - obtainAmmoList[0][1])+0.00001 
                    if (distAmmo/distEnemy2Ammo) < 2.0 :
                        goToAmmo = 0
                        for friend in obs.friends:
                            if obtainAmmoList[0][0]-20 < friend[0] < obtainAmmoList[0][0]+20 and obtainAmmoList[0][1]-20 < friend[1] < obtainAmmoList[0][1]+20:
                                goToAmmo = 1
                                print "should not grab with friends"
                        if goToAmmo == 0:
                            print "don't see friend???"
                            self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                        else:
                            self.goal = EscapeLoc + (4,)# RUSH!!!
                    else:
                        self.goal = EscapeLoc + (4,)# RUSH!!!
                # 1.3.7 agent sees Cp and Enemy and Ammo altogether
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList !=[]:
                    distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1])+0.00001 
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                    distEnemy2Cp = abs(obtainEnemyList[0][0] - obtainCPList[0][0])+abs(obtainEnemyList[0][1] - obtainCPList[0][1])+0.00001 
                    distEnemy2Ammo = abs(obtainEnemyList[0][0] - obtainAmmoList[0][0])+abs(obtainEnemyList[0][1] - obtainAmmoList[0][1])+0.00001 
                    if distCp < distEnemy2Cp and distAmmo > distEnemy2Ammo:
                        self.goal = obtainCPList[0] + (4,)# RUSH!!!
                    if distCp > distEnemy2Cp and distAmmo < distEnemy2Ammo:
                        self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                    if distCp < distEnemy2Cp and distAmmo < distEnemy2Ammo:
                        self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                    if distCp > distEnemy2Cp and distAmmo > distEnemy2Ammo:
                        self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                # 1.3.8 agent sees nothing
                if len(knownAmmos)<6 and obtainCPList ==[] and obtainAmmoList ==[] and obtainEnemyList ==[] :
                    self.goal = None
                    
            # obtain all Ammos' info, start computing
            if len(knownAmmos)==6 and obtainAmmoList==[] and obtainCPList ==[] and obtainEnemyList != []: #maybe need add Enemy
                    #compute cloest ammo and pick up
                    distAmmoList = []
                    for element in knownAmmos:
                        distAmmo = abs(obs.loc[0]-element[0][0])+abs(obs.loc[1]-element[0][1])
                        distAmmoList.append(distAmmo)
                    minIndex = distAmmoList.index(min(distAmmoList))
                    #check whether this ammo has been taken by friends
                    if AmmoTaken[minIndex]==0 or ( AmmoTaken[minIndex]==1 and self.id == AmmoTakenById[minIndex]):
                        AmmoTaken[minIndex]=1
                        AmmoTakenById[minIndex]=self.id
                        doAppendWaitingAgent = 0
                        if len(WaitingAmmoAgents)>0:
                            for waitingAgent in WaitingAmmoAgents:
                                if self.id == waitingAgent:
                                     doAppendWaitingAgent =1
                        if doAppendWaitingAgent == 0 :
                            WaitingAmmoAgents.append(self.id)
                        targetAmmo = knownAmmos[minIndex][0:2]
                        self.goal = targetAmmo[0]

          
        # 2.agent has Ammo
        elif obs.ammo>0:    
            # 2.1 agent is in Region-1 (DifferentRegion[0])
            if agentLoc[0] < DifferentRegion[0]:
                # 2.1.1 agent only sees Cp and Cp is closest one
                if obtainCPList !=[] and obtainAmmoList ==[] and obtainEnemyList ==[]:
                    self.goal = obtainCPList[0] 
                # 2.1.2 agent only sees Ammo
                if obtainAmmoList !=[] and obtainCPList ==[] and obtainEnemyList ==[]:
                    self.goal = None
                # 2.1.3 agent only sees Enemy----seldom run here
                if obtainEnemyList !=[] and obtainAmmoList ==[] and obtainCPList==[]:
                    self.goal = obtainEnemyList[0][0:2]
                # 2.1.4 agent sees Cp and Ammo together
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList ==[]:
                    self.goal = obtainCPList[0]
                # 2.1.5 agent sees Cp and Enemy together
                if obtainCPList !=[] and obtainEnemyList !=[] and obtainAmmoList ==[] :
                    self.goal = obtainEnemyList[0][0:2]
                # 2.1.6 agent sees Enemy and Ammo together
                if obtainEnemyList !=[] and obtainAmmoList !=[] and obtainCPList ==[] :
                    '''
                    distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                    distEnemy2Ammo = abs(obtainEnemyList[0][0] - obtainAmmoList[0][0])+abs(obtainEnemyList[0][1] - obtainAmmoList[0][1])+0.00001 
                    if (distAmmo/distEnemy2Ammo) < 2.0 :
                        self.goal = obtainAmmoList[0] + (4,)# RUSH!!!
                    else:
                    '''
                    self.goal = obtainEnemyList[0][0:2]
                # 2.1.7 agent sees Cp and Enemy and Ammo altogether
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList !=[]:
                    self.goal = obtainEnemyList[0][0:2]
                # 2.1.8 agent sees nothing
                if obtainCPList ==[] and obtainAmmoList ==[] and obtainEnemyList ==[] :
                    self.goal = None
                    
            # 2.2 agent is in Region-2 (DifferentRegion[0]-->DifferentRegion[2])
            elif DifferentRegion[0] <= agentLoc[0] < DifferentRegion[2]:
                # 2.2.1 agent only sees Cp and Cp is closest one
                if obtainCPList !=[] and obtainAmmoList ==[] and obtainEnemyList ==[]:
                    self.goal = obtainCPList[0] 
                # 2.2.2 agent only sees Ammo
                if obtainAmmoList !=[] and obtainCPList ==[] and obtainEnemyList ==[]:
                    self.goal = obtainAmmoList[0]
                # 2.2.3 agent only sees Enemy----seldom run here
                if obtainEnemyList !=[] and obtainAmmoList ==[] and obtainCPList==[]:
                    self.goal = obtainEnemyList[0][0:2]
                # 2.2.4 agent sees Cp and Ammo together
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList ==[]:
                    self.goal = obtainCPList[0]
                # 2.2.5 agent sees Cp and Enemy together
                if obtainCPList !=[] and obtainEnemyList !=[] and obtainAmmoList ==[] :
                    self.goal = obtainEnemyList[0][0:2]
                # 2.2.6 agent sees Enemy and Ammo together
                if obtainEnemyList !=[] and obtainAmmoList !=[] and obtainCPList ==[] :
                    self.goal = obtainEnemyList[0][0:2]
                # 2.2.7 agent sees Cp and Enemy and Ammo altogether
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList !=[]:
                    self.goal = obtainEnemyList[0][0:2]
                # 2.2.8 agent sees nothing
                if obtainCPList ==[] and obtainAmmoList ==[] and obtainEnemyList ==[] :
                    self.goal = None
                    
            # 2.3 agent is in Region-3 (DifferentRegion[2])
            elif agentLoc[0] >= DifferentRegion[2]:
                # 2.2.1 agent only sees Cp and Cp is closest one
                if obtainCPList !=[] and obtainAmmoList ==[] and obtainEnemyList ==[]:
                    self.goal = obtainCPList[0] 
                # 2.2.2 agent only sees Ammo
                if obtainAmmoList !=[] and obtainCPList ==[] and obtainEnemyList ==[]:
                    self.goal = obtainAmmoList[0]
                # 2.2.3 agent only sees Enemy----seldom run here
                if obtainEnemyList !=[] and obtainAmmoList ==[] and obtainCPList==[]:
                    self.goal = obtainEnemyList[0][0:2]
                # 2.2.4 agent sees Cp and Ammo together
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList ==[]:
                    self.goal = obtainAmmoList[0]
                # 2.2.5 agent sees Cp and Enemy together
                if obtainCPList !=[] and obtainEnemyList !=[] and obtainAmmoList ==[] :
                    self.goal = obtainEnemyList[0][0:2]
                # 2.2.6 agent sees Enemy and Ammo together
                if obtainEnemyList !=[] and obtainAmmoList !=[] and obtainCPList ==[] :
                    self.goal = obtainEnemyList[0][0:2]
                # 2.2.7 agent sees Cp and Enemy and Ammo altogether
                if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList !=[]:
                    self.goal = obtainEnemyList[0][0:2]
                # 2.2.8 agent sees nothing
                if obtainCPList ==[] and obtainAmmoList ==[] and obtainEnemyList ==[] :
                    self.goal = None
                    
                '''    
                unknownCps = [obs.cps[0][0:2] , obs.cps[1][0:2], obs.cps[2][0:2]]
                friendsLoc = obs.friends
                for cp in unknownCps:
                    #for friendLoc in friendsLoc:
                        #if friendLoc != cp :
                            if cp[0]-20<agentLoc[0]<cp[0]+20 and cp[1]-20<agentLoc[1]<cp[1]+20:
                                if obs.ammo>0:
                                #standOnCp = 1
                                #standOnCpId = self.id
                                    if len(self.goal) == 2:
                                        self.goal =self.goal+(2,)
                '''
        # 3. no matter where is agent, here is for corporation    
        # 3.1 attack Enemy base together
        if obtainCPList==[] and obs.ammo>3 and obtainEnemyList==[]: 
            print "Attack together@@@@@@"
            if  agentLoc[0] < DifferentRegion[2]: # only for red team
                self.goal = enemyInitialLoc
                print str(self.goal)+"Attack together and walk fast"
            else:
                self.goal = enemyInitialLoc+(1,) 
                print str(self.goal)+"Attack together and walk slow"
        '''
        # 3.1 help friends   
        if obs.ammo>0 and len(shallEnemy)>0:
                if shallFriend>0:
                    for member in shallFriend:
                        if agentLoc == member:
                            self.goal = shallEnemy
                            print "I have to help my friend"
        # shall enemy with friends
        if obtainEnemyList!=[] :
            shallEnemy = obtainEnemyList[0][0:2]
            shallFriend = obs.friends
        '''        
        # Walk to random CP
        if self.goal is None:
            self.goal = obs.cps[random.randint(0,len(obs.cps)-1)][0:2]+(-1,)
        
        
        return self.goal 
    
    def computeGoal(self):
            global AmmoTaken
            global AmmoTakenById 
            global WaitingAmmoAgents
            global standOnCp
            global standOnCpId
            global shallEnemy
            global shallFriend
            obs = self.observation
         # agent obatin 3 main goals
            obtainCPList = self.computeCpDist()
            obtainAmmoList = self.computAmmoDist()
            obtainEnemyList = self.computEnemyDist()
            
            #print obs.foes
            #print obtainEnemyList
            
            agentLoc = obs.loc;
            
                      
            # 1.I see CP and Ammo and Enemy at the same time
            if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList !=[]:
                #print "# 1.I see CP and Ammo and Enemy at the same time"
                # calculate 4 distances
                distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1])+0.00001 
                distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                distEnemy2Cp = abs(obtainEnemyList[0][0] - obtainCPList[0][0])+abs(obtainEnemyList[0][1] - obtainCPList[0][1])+0.00001 
                distEnemy2Ammo = abs(obtainEnemyList[0][0] - obtainAmmoList[0][0])+abs(obtainEnemyList[0][1] - obtainAmmoList[0][1])+0.00001 
                # I have no ammo, grab first
                if obs.ammo ==0:
                    if distCp < distEnemy2Cp and distAmmo > distEnemy2Ammo:
                        self.goal = obtainCPList[0]
                    if distCp > distEnemy2Cp and distAmmo < distEnemy2Ammo:
                        self.goal = obtainAmmoList[0]
                    if distCp < distEnemy2Cp and distAmmo < distEnemy2Ammo:
                        self.goal = obtainAmmoList[0]
                    if distCp > distEnemy2Cp and distAmmo > distEnemy2Ammo:
                        if distEnemy2Cp < distEnemy2Ammo:
                            self.goal = obtainAmmoList[0]
                        else :
                            self.goal = obtainCPList[0]
                # I have ammo, attack first
                elif obs.ammo >0:
                    if distEnemy2Cp < distEnemy2Ammo:
                        if distCp < distEnemy2Cp:#(distCp/distEnemy2Cp)<(1.0/2):
                            self.goal = obtainCPList[0]
                        else:
                            self.goal = obtainEnemyList[0][0:2]
                    else: 
                        if distAmmo < distEnemy2Ammo:#(distAmmo/distEnemy2Ammo)<(1.0/2):
                            self.goal = obtainAmmoList[0]
                        else:
                            self.goal = obtainEnemyList[0][0:2]
                            
            # 2.I see CP and Ammo at the same time
            if obtainCPList !=[] and obtainAmmoList !=[] and obtainEnemyList ==[]:
                 #print "# 2.I see CP and Ammo at the same time"
                 # calculate 2 distances
                 distCp=abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) +0.00001 
                 distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1]) +0.00001 
                 # I have no ammo, grab first
                 if obs.ammo ==0:
                     self.goal = obtainAmmoList[0]
                 elif obs.ammo >0 and obs.ammo<=3:
                     if (distAmmo/distCp)<(1.0/3):
                         self.goal = obtainAmmoList[0]
                     else:
                         self.goal = obtainCPList[0]
                 elif obs.ammo >3:
                     self.goal = obtainCPList[0]
            
            # 3.I see Cp and Enemy at the same time
            if obtainCPList !=[] and obtainEnemyList !=[] and obtainAmmoList ==[] :
                #print "# 3.I see Cp and Enemy at the same time"
                # calculate 2 distances
                distCp = abs(agentLoc[0] - obtainCPList[0][0])+abs(agentLoc[1] - obtainCPList[0][1]) +0.00001 
                distEnemy2Cp = abs(obtainEnemyList[0][0] - obtainCPList[0][0])+abs(obtainEnemyList[0][1] - obtainCPList[0][1])+0.00001 
                # I have no ammo, rush to Cp
                if obs.ammo ==0:
                    self.goal = obtainCPList[0]
                # I have ammo, consider attack first
                else:
                    if distCp < distEnemy2Cp:#(distCp/distEnemy2Cp)<(1.0/2):
                        self.goal = obtainCPList[0]
                    else:
                        self.goal = obtainEnemyList[0][0:2]
            
            # 4.I see Ammo and Enemy at the same time
            if obtainEnemyList !=[] and obtainAmmoList !=[] and obtainCPList ==[] :
                #print "# 4.I see Ammo and Enemy at the same time"
                # calculate 2 distances
                distAmmo=abs(agentLoc[0] - obtainAmmoList[0][0])+abs(agentLoc[1] - obtainAmmoList[0][1])+0.00001 
                distEnemy2Ammo = abs(obtainEnemyList[0][0] - obtainAmmoList[0][0])+abs(obtainEnemyList[0][1] - obtainAmmoList[0][1])+0.00001 
                # I have no ammo, grab first
                if obs.ammo==0:
                    self.goal = obtainAmmoList[0]
                else:
                    if (distAmmo/distEnemy2Ammo)<(1.0/2):
                        self.goal = obtainAmmoList[0]
                    else:
                        self.goal = obtainEnemyList[0][0:2]
            
            # 5.I only see Cp
            if obtainCPList !=[] and obtainAmmoList ==[] and obtainEnemyList ==[] :
                #print "# 5.I only see Cp"
                self.goal = obtainCPList[0]
            # 6.I only see ammo
            if obtainAmmoList !=[] and obtainCPList ==[] and obtainEnemyList ==[] :
                #print "# 6.I only see ammo"
                self.goal = obtainAmmoList[0]
            # 7.I only see enemy
            if obtainEnemyList !=[] and obtainAmmoList ==[] and obtainCPList==[] :
                #print "# 7.I only see enemy"
                self.goal = obtainEnemyList[0][0:2]
            # 8.I see nothing
            if obtainCPList ==[] and obtainAmmoList ==[] and obtainEnemyList ==[] :
                #print "# 8.I see nothing"
                self.goal = None
            
             # Walk to random CP
            if self.goal is None:
                #self.goal = obs.cps[random.randint(0,len(obs.cps)-1)][0:2]   
                print "I have no goal"
                
            #obatin all ammos' info, start computing
            if len(knownAmmos)==6 and obtainAmmoList==[] and obs.ammo==0:
                
                    #compute cloest ammo and pick up
                    distAmmoList = []
                    for element in knownAmmos:
                        distAmmo = abs(obs.loc[0]-element[0][0])+abs(obs.loc[1]-element[0][1])
                        distAmmoList.append(distAmmo)
                    minIndex = distAmmoList.index(min(distAmmoList))
                    #check whether this ammo has been taken by friends
                    if AmmoTaken[minIndex]==0 or ( AmmoTaken[minIndex]==1 and self.id == AmmoTakenById[minIndex]):
                        AmmoTaken[minIndex]=1
                        AmmoTakenById[minIndex]=self.id
                        doAppendWaitingAgent = 0
                        if len(WaitingAmmoAgents)>0:
                            for waitingAgent in WaitingAmmoAgents:
                                if self.id == waitingAgent:
                                     doAppendWaitingAgent =1
                        if doAppendWaitingAgent == 0 :
                            WaitingAmmoAgents.append(self.id)
                        
                        targetAmmo = knownAmmos[minIndex][0:2]
                        self.goal = targetAmmo[0]
                    #else:
                        #print "the closest ammo goal has been taken = " +str(knownAmmos[minIndex][0:2])
                 
            if obtainCPList==[] and obs.ammo>2 and obtainEnemyList==[]: 
                    if  agentLoc[0]<enemyInitialLoc[0]-200:
                        self.goal = enemyInitialLoc
                        print str(self.goal)+"Attack together and walk fast"
                    else:
                        self.goal = enemyInitialLoc+(1,) 
                        print str(self.goal)+"Attack together and walk slow"
            
            if obs.ammo>0 and len(shallEnemy)>0:
                if shallFriend>0:
                    for member in shallFriend:
                        if agentLoc == member:
                            self.goal = shallEnemy
                            print "I have to help my friend"
            # shall enemy with friends
            if obtainEnemyList!=[] :
                shallEnemy = obtainEnemyList[0][0:2]
                shallFriend = obs.friends
                
            
            unknownCps = [obs.cps[0][0:2] , obs.cps[1][0:2], obs.cps[2][0:2]]
            friendsLoc = obs.friends
            for cp in unknownCps:
                #for friendLoc in friendsLoc:
                    #if friendLoc != cp :
                        if cp[0]-20<agentLoc[0]<cp[0]+20 and cp[1]-20<agentLoc[1]<cp[1]+20:
                            if obs.ammo>0:
                            #standOnCp = 1
                            #standOnCpId = self.id
                                if len(self.goal) == 2:
                                    self.goal =self.goal+(2,)
                    

                
            return self.goal         
               
               
    def computeShoot(self):
            obs = self.observation
            # agent obatin 3 main goals
            obtainEnemyList = self.computEnemyDist()         
            # Shoot enemies
            shoot = False
            if (obs.ammo > 0 and 
                obtainEnemyList and 
                point_dist(obtainEnemyList[0][0:2], obs.loc) < self.settings.max_range
                and not line_intersects_grid(obs.loc, obtainEnemyList[0][0:2], self.grid, self.settings.tilesize)):
                self.goal = obtainEnemyList[0][0:2]
                shoot = True 
                # check whether shoot a friend
                angleEnemy = math.atan2(self.goal[0]-obs.loc[0],self.goal[1]-obs.loc[1])
                for member in obs.friends:
                    angleFriend = math.atan2(member[0]-obs.loc[0],member[1]-obs.loc[1])
                    #if   angleFriend == angleEnemy:
                    if  angleEnemy-0.25 <= angleFriend <= angleEnemy+0.25:
                        shoot = False
                        #print "I cannot shoot a friend in the Same angle!!!!!"
                #print self.goal
                # check whether shoot enemy base
                #if self.goal[0] >= enemyInitialLoc[0] and enemyInitialLoc[1]<=self.goal[1]<=enemyInitialLoc[1]+30:# for red team
                    #shoot = False
                    #print "I cannot shoot in the base"        
            return shoot
